package com.appkubes.fintech.common.plan;

import cn.hutool.core.date.DateUtil;
import com.appkubes.fintech.common.exption.BusinessException;
import org.apache.commons.lang3.time.DateUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @description: 还款计划计算公式
 * @author: xqc
 * @date: 2020/1/2 20:30
 * @params:
 * @return:
 */
public class BillPlaneUtile {

    /**
     * @description:
     * @author: xqc
     * @date: 2020/1/15 15:49
     * @params: periodType 期限类型   periods 期数  periodLong 总时长 单位为天必填  totalAmt 总租金金额   rate利息
     * @return:
     */
    public static BillInfoVo planBill(Integer periodType, Integer periods, Integer periodLong, Integer totalAmt, BigDecimal rate){
        if(Objects.equals(periodType, RentPeriodTypeEnums.天.getValue())){ // 天计算
            return planDayBill(periods,periodLong,totalAmt,rate);
        }
        else if(Objects.equals(periodType,RentPeriodTypeEnums.周.getValue())){  // 周计算
            return planWeekBill(periods,periodLong,totalAmt,rate);
        }
        else if(Objects.equals(periodType,RentPeriodTypeEnums.月.getValue())){ // 月计算
            return planMonthBill(periods,periodLong,totalAmt,rate);
        }
        else{
            throw new BusinessException("期数类型错误");
        }
    }
    private static BillInfoVo planDayBill(Integer periods,Integer totalDays,Integer totalAmt,BigDecimal rate){
        BillInfoVo billInfoVo=new BillInfoVo();
       // 总利息
        Integer totalInterest=new BigDecimal(totalAmt).multiply(new BigDecimal(periods)).multiply(rate).setScale(0,BigDecimal.ROUND_HALF_UP).intValue();

        Integer len=totalDays/periods;// 间隔天数
        Integer surDay=totalDays-len*periods; // 余下天数
        //Date startDate= DateUtils.addDays(new Date(),1);
        Date startDate= new Date();
        Date beginDate= new Date();
        Integer repayAmt=totalAmt/periods; // 每期应还金额
        Integer repayInterestAmt=totalInterest/periods; //每期数 应还 利息
        Integer surAmt=totalAmt-repayAmt*periods;; // 剩余本金
        Integer surInteresAmt=totalInterest-repayInterestAmt*periods; // 剩余利息
        List<BillDetailVo> voList=new ArrayList<>();
        for(int i=1;i<=periods;i++){
            int periodDay=len;
            int periodAmt=repayAmt;
            int periodInterestAmt=repayInterestAmt;
            if(Objects.equals(i,1)){  //第一期加上剩余天数
                periodAmt+=surAmt;
                periodInterestAmt+=surInteresAmt;
            }
            if(surDay>0){  // 多余天数顺次加下去
                periodDay++;
                surDay--;
            }
            BillDetailVo vo=new BillDetailVo();
            vo.setPeriod(i);
            vo.setStartDate(DateUtil.format(startDate,"yyyy-MM-dd"));
            vo.setEndDate(DateUtil.format(DateUtils.addDays(startDate,periodDay),"yyyy-MM-dd"));
            vo.setPayAmt(periodAmt);
            vo.setPayInterestAmt(periodInterestAmt);
            vo.setDays(periodDay);
            voList.add(vo);
            startDate= DateUtil.parse(vo.getEndDate(),"yyyy-MM-dd");
        }
        billInfoVo.setInterestRate(rate);
        billInfoVo.setDetailVoList(voList);
        billInfoVo.setStartDate(DateUtil.format(beginDate,"yyyy-MM-dd"));
        billInfoVo.setEndDate(DateUtil.format(DateUtils.addDays(beginDate,totalDays),"yyyy-MM-dd"));
        billInfoVo.setPeriods(periods);
        billInfoVo.setInterestAmt(totalInterest); // 总利息
        billInfoVo.setPrincipalAmt(totalAmt); // 总本金
        return billInfoVo;
    }

    private static BillInfoVo planMonthBill(Integer periods,Integer totalMonth,Integer totalAmt,BigDecimal rate){
        BillInfoVo billInfoVo=new BillInfoVo();
        //Date startDate= DateUtils.addDays(new Date(),1);
        Date startDate= new Date();
        Date beginDate= new Date();
        Integer repayAmt=totalAmt/periods; // 每期应还金额
        Integer surAmt=totalAmt-repayAmt*periods;
// 总利息
        Integer totalInterest=new BigDecimal(totalAmt).multiply(new BigDecimal(periods)).multiply(rate).setScale(0,BigDecimal.ROUND_HALF_UP).intValue();
        Integer repayInterestAmt=totalInterest/periods; //每期数 应还 利息
        Integer surInteresAmt=totalInterest-repayInterestAmt*periods; // 剩余利息

        List<BillDetailVo> voList=new ArrayList<>();
        for(int i=1;i<=periods;i++){
            int periodAmt=repayAmt;
            int periodInterestAmt=repayInterestAmt;
            if(Objects.equals(i,1)){  //第一期加上剩余天数
                periodAmt+=surAmt;
                periodInterestAmt+=surInteresAmt;
            }
            BillDetailVo vo=new BillDetailVo();
            vo.setPeriod(i);
            vo.setStartDate(DateUtil.format(startDate,"yyyy-MM-dd"));
            vo.setEndDate(DateUtil.format(DateUtils.addMonths(startDate,1),"yyyy-MM-dd"));
            vo.setPayAmt(periodAmt);
            vo.setPayInterestAmt(periodInterestAmt);
            Long days= DateUtil.betweenDay(startDate, DateUtils.addMonths(startDate,1),false);
            vo.setDays(days.intValue());
            voList.add(vo);
            startDate= DateUtil.parse(vo.getEndDate(),"yyyy-MM-dd");
        }
        billInfoVo.setInterestRate(rate);
        billInfoVo.setDetailVoList(voList);
        billInfoVo.setStartDate(DateUtil.format(beginDate,"yyyy-MM-dd"));
        billInfoVo.setEndDate(DateUtil.format(DateUtils.addMonths(beginDate,periods),"yyyy-MM-dd"));
        billInfoVo.setPeriods(periods);
        billInfoVo.setPrincipalAmt(totalAmt);
        billInfoVo.setInterestAmt(totalInterest);
        return billInfoVo;
    }


    private static BillInfoVo planWeekBill(Integer periods,Integer totalMonth,Integer totalAmt,BigDecimal rate){
        BillInfoVo billInfoVo=new BillInfoVo();
        //Date startDate= DateUtils.addDays(new Date(),1);
        Date startDate= new Date();
        Date beginDate= new Date();
        Integer repayAmt=totalAmt/periods; // 每期应还金额
        Integer surAmt=totalAmt-repayAmt*periods;
        // 总利息
        Integer totalInterest=new BigDecimal(totalAmt).multiply(new BigDecimal(periods)).multiply(rate).setScale(0,BigDecimal.ROUND_HALF_UP).intValue();
        Integer repayInterestAmt=totalInterest/periods; //每期数 应还 利息
        Integer surInteresAmt=totalInterest-repayInterestAmt*periods; // 剩余利息
        List<BillDetailVo> voList=new ArrayList<>();
        for(int i=1;i<=periods;i++){
            int periodAmt=repayAmt;
            int periodInterestAmt=repayInterestAmt;
            if(Objects.equals(i,1)){  //第一期加上剩余天数
                periodAmt+=surAmt;
                periodInterestAmt+=surInteresAmt;
            }
            BillDetailVo vo=new BillDetailVo();
            vo.setPeriod(i);
            vo.setStartDate(DateUtil.format(startDate,"yyyy-MM-dd"));
            vo.setEndDate(DateUtil.format(DateUtils.addWeeks(startDate,1),"yyyy-MM-dd"));
            vo.setPayAmt(periodAmt);
            vo.setPayInterestAmt(periodInterestAmt);
            Long days= DateUtil.betweenDay(startDate, DateUtils.addWeeks(startDate,1),false);
            vo.setDays(days.intValue());
            voList.add(vo);
            startDate= DateUtil.parse(vo.getEndDate(),"yyyy-MM-dd");
        }
        billInfoVo.setInterestRate(rate);
        billInfoVo.setDetailVoList(voList);
        billInfoVo.setStartDate(DateUtil.format(beginDate,"yyyy-MM-dd"));
        billInfoVo.setEndDate(DateUtil.format(DateUtils.addWeeks(beginDate,periods),"yyyy-MM-dd"));
        billInfoVo.setPeriods(periods);
        billInfoVo.setPrincipalAmt(totalAmt);
        billInfoVo.setInterestAmt(totalInterest);
        return billInfoVo;
    }
    public static void main(String[] args) {
    //  BillInfoVo billInfoVo=  planDayBill(6,100,7000,new BigDecimal(0.003));
//      System.out.println("总本金:"+billInfoVo.getPrincipalAmt()+"总利息："+billInfoVo.getInterestAmt()+"总期数："+billInfoVo.getPeriods()
//              +" 租金利率："+billInfoVo.getInterestRate().setScale(3,BigDecimal.ROUND_HALF_UP)
//              +" 开始日期："  +billInfoVo.getStartDate()+"  结束日期："+billInfoVo.getEndDate());
//      billInfoVo.getDetailVoList().forEach(e->{
//          System.out.println("期数："+e.getPeriod()+"  天数："+e.getDays()+"  开始：" +e.getStartDate()
//                  +"  结束："+e.getEndDate()+"  本金："+e.getPayAmt()+" 利息："+e.getPayInterestAmt());
//
//      });

//        BillInfoVo billInfoVo=  planMonthBill(5,5,7000,new BigDecimal(0.003));
//        System.out.println("总本金:"+billInfoVo.getPrincipalAmt()+"总利息："+billInfoVo.getInterestAmt()+"总期数："+billInfoVo.getPeriods()
//                +" 租金利率："+billInfoVo.getInterestRate().setScale(3,BigDecimal.ROUND_HALF_UP)
//                +" 开始日期："  +billInfoVo.getStartDate()+"  结束日期："+billInfoVo.getEndDate());
//        billInfoVo.getDetailVoList().forEach(e->{
//            System.out.println("期数："+e.getPeriod()+"  天数："+e.getDays()+"  开始：" +e.getStartDate()
//                    +"  结束："+e.getEndDate()+"  本金："+e.getPayAmt()+" 利息："+e.getPayInterestAmt());
//
//        });

        BillInfoVo billInfoVo=  planWeekBill(5,5,7000,new BigDecimal(0.01));
        System.out.println("总本金:"+billInfoVo.getPrincipalAmt()+"总利息："+billInfoVo.getInterestAmt()+"总期数："+billInfoVo.getPeriods()
                +" 租金利率："+billInfoVo.getInterestRate().setScale(3,BigDecimal.ROUND_HALF_UP)
                +" 开始日期："  +billInfoVo.getStartDate()+"  结束日期："+billInfoVo.getEndDate());
        billInfoVo.getDetailVoList().forEach(e->{
            System.out.println("期数："+e.getPeriod()+"  天数："+e.getDays()+"  开始：" +e.getStartDate()
                    +"  结束："+e.getEndDate()+"  本金："+e.getPayAmt()+" 利息："+e.getPayInterestAmt());

        });
    }
}
